/**
 * 灵活的WebSocket消息解析器
 * 支持可变数据格式和自定义数据提取路径
 */

import type { DataParsingRule } from '@/services/websocket';

export interface ParsedDataPoint {
  id: string;
  value: any;
  path: string; // 原始数据路径
}

export class MessageParser {
  /**
   * 根据解析规则解析WebSocket消息
   */
  static parseMessage(
    message: any,
    sourceId: string,
    parsingRule?: DataParsingRule
  ): ParsedDataPoint[] {
    console.log('[MessageParser] 开始解析消息:', { message, sourceId, parsingRule });

    if (!parsingRule) {
      // 默认解析规则：自动提取所有字段
      return this.autoParseMessage(message, sourceId);
    }

    switch (parsingRule.pointExtraction) {
      case 'auto':
        return this.autoParseWithRule(message, sourceId, parsingRule);
      case 'manual':
        return this.manualParseWithRule(message, sourceId, parsingRule);
      case 'custom':
        return this.customParseWithRule(message, sourceId, parsingRule);
      default:
        return this.autoParseMessage(message, sourceId);
    }
  }

  /**
   * 自动解析消息（默认行为）
   */
  private static autoParseMessage(message: any, sourceId: string): ParsedDataPoint[] {
    const results: ParsedDataPoint[] = [];

    if (typeof message !== 'object' || message === null) {
      // 简单值
      results.push({
        id: `${sourceId}_${Date.now()}`,
        value: message,
        path: '$'
      });
      return results;
    }

    // 递归解析对象
    this.extractDataPoints(message, '', results);
    console.log('[MessageParser] 自动解析结果:', results);
    return results;
  }

  /**
   * 带规则的自动解析
   */
  private static autoParseWithRule(
    message: any,
    sourceId: string,
    rule: DataParsingRule
  ): ParsedDataPoint[] {
    const results: ParsedDataPoint[] = [];

    // 如果指定了数据路径，先提取该路径的数据
    let dataToProcess = message;
    if (rule.dataPath) {
      dataToProcess = this.extractDataByPath(message, rule.dataPath);
      console.log('[MessageParser] 按路径提取数据:', { path: rule.dataPath, data: dataToProcess });
    }

    if (typeof dataToProcess !== 'object' || dataToProcess === null) {
      results.push({
        id: `${sourceId}_single`,
        value: dataToProcess,
        path: rule.dataPath || '$'
      });
      return results;
    }

    // 自动提取数据点，排除指定字段
    const excludeFields = rule.excludeFields || ['action', 'type', 'timestamp', 'line', 'source'];

    this.extractDataPoints(dataToProcess, rule.dataPath || '', results, excludeFields);

    console.log('[MessageParser] 带规则自动解析结果:', results);
    return results;
  }

  /**
   * 手动字段映射解析
   */
  private static manualParseWithRule(
    message: any,
    sourceId: string,
    rule: DataParsingRule
  ): ParsedDataPoint[] {
    const results: ParsedDataPoint[] = [];

    if (!rule.fieldMappings || rule.fieldMappings.length === 0) {
      console.warn('[MessageParser] 手动解析模式但未配置字段映射');
      return results;
    }

    for (const mapping of rule.fieldMappings) {
      try {
        const value = this.extractDataByPath(message, mapping.sourcePath);
        if (value !== undefined) {
          results.push({
            id: mapping.pointId,
            value: value,
            path: mapping.sourcePath
          });
        }
      } catch (error) {
        console.warn(`[MessageParser] 解析字段映射失败: ${mapping.sourcePath}`, error);
      }
    }

    console.log('[MessageParser] 手动映射解析结果:', results);
    return results;
  }

  /**
   * 自定义解析函数
   */
  private static customParseWithRule(
    message: any,
    sourceId: string,
    rule: DataParsingRule
  ): ParsedDataPoint[] {
    if (!rule.customParser) {
      console.warn('[MessageParser] 自定义解析模式但未提供解析函数');
      return this.autoParseMessage(message, sourceId);
    }

    try {
      // 创建安全的执行环境
      const parseFunction = new Function(
        'message',
        'sourceId',
        'utils',
        `
        const results = [];
        ${rule.customParser}
        return results;
        `
      );

      // 提供工具函数
      const utils = {
        extractByPath: (obj: any, path: string) => this.extractDataByPath(obj, path),
        createDataPoint: (id: string, value: any, path: string = '') => ({ id, value, path })
      };

      const results = parseFunction(message, sourceId, utils);
      console.log('[MessageParser] 自定义解析结果:', results);
      return Array.isArray(results) ? results : [];
    } catch (error) {
      console.error('[MessageParser] 自定义解析函数执行失败:', error);
      return this.autoParseMessage(message, sourceId);
    }
  }

  /**
   * 按路径提取数据
   * 支持简单的dot notation和简单的JSONPath
   */
  private static extractDataByPath(obj: any, path: string): any {
    if (!path || path === '$' || path === '.') {
      return obj;
    }

    // 处理JSONPath格式
    if (path.startsWith('$.')) {
      path = path.substring(2);
    } else if (path.startsWith('$')) {
      path = path.substring(1);
    }

    // 简单的dot notation解析
    const parts = path.split('.');
    let current = obj;

    for (const part of parts) {
      if (current === null || current === undefined) {
        return undefined;
      }

      // 处理数组索引
      if (part.includes('[') && part.includes(']')) {
        const [key, indexStr] = part.split('[');
        const index = parseInt(indexStr.replace(']', ''));
        current = current[key];
        if (Array.isArray(current) && index >= 0 && index < current.length) {
          current = current[index];
        } else {
          return undefined;
        }
      } else {
        current = current[part];
      }
    }

    return current;
  }

  /**
   * 递归提取数据点
   */
  private static extractDataPoints(
    obj: any,
    basePath: string,
    results: ParsedDataPoint[],
    excludeFields: string[] = []
  ): void {
    if (typeof obj !== 'object' || obj === null) {
      return;
    }

    Object.entries(obj).forEach(([key, value]) => {
      // 跳过排除字段
      if (excludeFields.includes(key)) {
        return;
      }

      const currentPath = basePath ? `${basePath}.${key}` : key;

      if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
        // 递归处理嵌套对象
        this.extractDataPoints(value, currentPath, results, excludeFields);
      } else {
        // 添加数据点
        results.push({
          id: key,
          value: value,
          path: currentPath
        });
      }
    });
  }

  /**
   * 生成默认解析规则
   */
  static getDefaultParsingRule(): DataParsingRule {
    return {
      pointExtraction: 'auto',
      excludeFields: ['action', 'type', 'timestamp', 'line', 'source']
    };
  }

  /**
   * 生成嵌套数据的解析规则
   */
  static getNestedDataParsingRule(dataPath: string = 'data'): DataParsingRule {
    return {
      dataPath: dataPath,
      pointExtraction: 'auto',
      excludeFields: ['action', 'type', 'timestamp', 'line', 'source']
    };
  }

  /**
   * 验证解析规则
   */
  static validateParsingRule(rule: DataParsingRule): string[] {
    const errors: string[] = [];

    if (
      rule.pointExtraction === 'manual' &&
      (!rule.fieldMappings || rule.fieldMappings.length === 0)
    ) {
      errors.push('手动解析模式必须配置字段映射');
    }

    if (rule.pointExtraction === 'custom' && !rule.customParser) {
      errors.push('自定义解析模式必须提供解析函数');
    }

    if (rule.fieldMappings) {
      rule.fieldMappings.forEach((mapping, index) => {
        if (!mapping.sourcePath || !mapping.pointId) {
          errors.push(`字段映射 ${index + 1} 缺少必要配置`);
        }
      });
    }

    return errors;
  }
}
